Technical Q&A QA1165
Internet Connect Speed


Q: Mac OS X でモデム接続速度を取得するにはどうしたらよいですか?Internet Connect の表示と同じ値を取得する必要があります。

A: この情報は、System Configuration フレームワークのダイナミックストアから取得できます。モデムが接続すると、PPP コントローラはその接続速度を、ネットワークサービス状況の kSCEntNetModem エンティティの kSCPropNetModemConnectSpeed プロパティに格納します。リスト 1 に示すコードは、接続されたモデムサービスごとにこの情報を表示します。



リスト 1. モデム接続速度の取得

static void PrintConnectionSpeed(const void *key, 
                                 const void *value, 
                                 void *context)
    // CFDictionaryApplyFunction コールバック。キーは、モデム
    // ネットワークサービスエンティティのSCF ダイナミックストアキー。
    // 値は、エンティティディクショナリ。これにより、エンティティから
    // 接続速度プロパティを抽出し、表示する
{
    CFStringRef       dynStoreKey;
    CFDictionaryRef   entityDict;
    CFNumberRef       connectionSpeed;
    #pragma unused(context)
    
    dynStoreKey = (CFStringRef) key;
    entityDict  = (CFDictionaryRef) value;
    
    assert( CFGetTypeID(dynStoreKey) == CFStringGetTypeID()     );
    assert( CFGetTypeID(entityDict)  == CFDictionaryGetTypeID() );
    
    connectionSpeed = (CFNumberRef) CFDictionaryGetValue(entityDict, 
                                       kSCPropNetModemConnectSpeed);
    if (connectionSpeed == NULL) {
        // 切断されたモデルエンティティには、接続速度プロパティはない。
        // このサンプルでは、単に無視する
    } else {
        CFStringRef str;
        
        assert( CFGetTypeID(connectionSpeed) == CFNumberGetTypeID() );
        
        str = CFStringCreateWithFormat(NULL, NULL, 
                                       CFSTR("%@ = %@"), 
                                       dynStoreKey, 
                                       connectionSpeed);
        assert(str != NULL);

        CFShow(str);
        
        CFQRelease(str);
    }
}

int main (int argc, const char * argv[])
{
    OSStatus            err;
    SCDynamicStoreRef   store;
    CFStringRef         pattern;
    CFArrayRef          patterns;
    CFDictionaryRef     dictOfModemEntities;
    
    dictOfModemEntities = NULL;
    pattern  = NULL;
    patterns = NULL;
    
    // ダイナミックストアに接続する
    
    store = SCDynamicStoreCreate(NULL, CFSTR("ConnectionSpeedTest"), 
                                                        NULL, NULL);
    err = MoreSCError(store);
    
    // pattern を“State:/Network/Service/[^/]+/Modem”に設定し、
    // これを CFArray に入れる

    if (err == noErr) {
        pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, 
                                        kSCDynamicStoreDomainState, 
                                        kSCCompAnyRegex,
                                        kSCEntNetModem);
        err = MoreSCError(pattern);
    }
    if (err == noErr) {
        patterns = CFArrayCreate(NULL, (const void **) &pattern, 1, 
                                            &kCFTypeArrayCallBacks);
        err = CFQError(patterns);
    }

    // ダイナミックストアからすべてのモデムネットワークサービス
    // エンティティを取得し、結果を表示する
    
    if (err == noErr) {
        dictOfModemEntities = SCDynamicStoreCopyMultiple(store, 
                                                    NULL, patterns);
        err = MoreSCError(dictOfModemEntities);
    }
    if (err == noErr) {
        CFDictionaryApplyFunction(dictOfModemEntities, 
                                        PrintConnectionSpeed, NULL);
    }
    
    // クリーンアップ
    
    CFQRelease(store);
    CFQRelease(pattern);
    CFQRelease(patterns);
    CFQRelease(dictOfModemEntities);
    
    return (err != noErr);
}


このコードでは、DTS MoreSCF サンプルコードに記載されている 3 つのヘルパー関数(CFQErrorCFQReleaseMoreSCError)を使用します。


[2003 年 3 月 19 日]